home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / The World of Computer Software.iso / superopt.zip / SUPEROPT.H < prev    next >
C/C++ Source or Header  |  1992-11-21  |  20KB  |  652 lines

  1. /* Superoptimizer definitions.
  2.  
  3.    Copyright (C) 1991, 1992 Free Software Foundation, Inc.
  4.  
  5.    This program is free software; you can redistribute it and/or modify it
  6.    under the terms of the GNU General Public License as published by the
  7.    Free Software Foundation; either version 2, or (at your option) any
  8.    later version.
  9.  
  10.    This program is distributed in the hope that it will be useful, but
  11.    WITHOUT ANY WARRANTY; without even the implied warranty of
  12.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.    General Public License for more details.
  14.  
  15.    You should have received a copy of the GNU General Public License along
  16.    with this program; see the file COPYING.  If not, write to the Free
  17.    Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  18.  
  19. #if !(defined(SPARC) || defined(RS6000)    || defined(M88000)        \
  20.       || defined(AM29K) || defined(M68000) || defined(I386) || defined(PYR))
  21. /* If no target instruction set is defined, use host instruction set.  */
  22. #define SPARC (defined(sparc) || defined(__sparc__))
  23. #define RS6000 (defined(rs6000) || defined(_IBMR2))
  24. #define M88000 (defined(m88000) || defined(__m88000__))
  25. #define AM29K (defined(_AM29K) || defined(_AM29000))
  26. #define M68000 (defined(m68000) || defined(mc68000))
  27. #define I386 (defined(i386) || defined(i80386))
  28. #define PYR (defined(pyr) || defined(__pyr__))
  29. #endif
  30.  
  31. #if !(SPARC || RS6000 || M88000 || AM29K || M68000 || I386 || PYR)
  32. #error: you have to choose target CPU type (e.g. -DSPARC).
  33. #endif
  34.  
  35. #include "longlong.h"
  36.  
  37. #define BITS_PER_WORD 32
  38.  
  39. #define TRUNC_CNT(cnt) ((cnt) & (BITS_PER_WORD - 1))
  40.  
  41. #if defined(sparc) || defined(__GNUC__)
  42. #define alloca __builtin_alloca
  43. #endif
  44.  
  45. #if !defined(__GNUC__) || !defined(__OPTIMIZE__)
  46. #define inline /* Empty */
  47. #endif
  48.  
  49. typedef unsigned long int unsigned_word;
  50. typedef signed long int signed_word;
  51. typedef unsigned_word word;
  52.  
  53. /* The IMMEDIATE_* macros are for printing assembler.  NOT for sequence
  54.    generating ot analyze.  */
  55. #define IMMEDIATE_P(op) (op >= 0x20 - 3)
  56. static const word __immediate_val[] =
  57. {
  58.   1 << (BITS_PER_WORD - 1),
  59.   (1 << (BITS_PER_WORD - 1)) - 1,
  60. };
  61. #define IMMEDIATE_VAL(op) \
  62.   ((op) >= 0x20 - 1 ? op - 0x20 : __immediate_val[0x20 - 2 - (op)])
  63.  
  64. /* Handle immediates by putting all handled values in the VALUE array at
  65.    appropriate indices, and then insert these indices in the code???
  66.    Interesting constants are probably 0, 1, -1, 0x80000000, and
  67.    0x7FFFFFFF.  */
  68.  
  69. #define CNST_0x80000000    (0x20 - 2)
  70. #define CNST_0x7FFFFFFF (0x20 - 3)
  71.  
  72. #define VALUE_MIN_SIGNED 0x80000000
  73. #define VALUE_MAX_SIGNED 0x7fffffff
  74.  
  75. #define CNST(n) (0x20 + n)
  76. #define VALUE(n) n
  77.  
  78. typedef enum
  79. {
  80. #undef    DEF_INSN
  81. #define DEF_INSN(SYM,CLASS,NAME) SYM,
  82. #include "insn.def"
  83. } opcode_t;
  84.  
  85. #define GET_INSN_CLASS(OP) (insn_class[OP])
  86. #define GET_INSN_NAME(OP) (insn_name[OP])
  87.  
  88. #define UNARY_OPERATION(insn) (GET_INSN_CLASS (insn.opcode) == '1')
  89.  
  90. typedef struct
  91. {
  92.   opcode_t opcode:8;
  93.   unsigned int s1:8;
  94.   unsigned int s2:8;
  95.   unsigned int d:8;
  96. } insn_t;
  97.  
  98. /* PERFORM_* for all instructions the search uses.  These macros are
  99.    used both in the search phase and in the test phase.  */
  100.  
  101. #if defined(__GNUC__) && defined(USE_ASM)
  102. /*** Define machine-dependent PERFORM_* here to improve synthesis speed ***/
  103.  
  104. #if sparc
  105. #define PERFORM_ADD_CIO(d, co, r1, r2, ci) \
  106.   asm ("subcc %%g0,%4,%%g0    ! set cy if CI != 0
  107.     addxcc %2,%3,%0        ! add R1 and R2
  108.     addx %%g0,%%g0,%1    ! set CO to cy"                \
  109.        : "=r" (d), "=r" (co)                        \
  110.        : "%r" (r1), "rI" (r2), "rI" (ci)                \
  111.        : "cc")
  112. #define PERFORM_ADD_CO(d, co, r1, r2, ci) \
  113.   asm ("addcc %2,%3,%0        ! add R1 and R2
  114.     addx %%g0,%%g0,%1    ! set CO to cy"                \
  115.        : "=r" (d), "=r" (co)                        \
  116.        : "%r" (r1), "rI" (r2)                        \
  117.        : "cc")
  118. #define PERFORM_SUB_CIO(d, co, r1, r2, ci) \
  119.   asm ("subcc %%g0,%4,%%g0    ! set cy if CI != 0
  120.     subxcc %2,%3,%0        ! subtract R2 from R1
  121.     addx %%g0,%%g0,%1    ! set CO to cy"                \
  122.        : "=r" (d), "=r" (co)                        \
  123.        : "r" (r1), "rI" (r2), "rI" (ci)                    \
  124.        : "cc")
  125. #define PERFORM_SUB_CO(d, co, r1, r2, ci) \
  126.   asm ("subcc %2,%3,%0        ! subtract R2 from R1
  127.     addx %%g0,%%g0,%1    ! set CO to cy"                \
  128.        : "=r" (d), "=r" (co)                        \
  129.        : "r" (r1), "rI" (r2)                        \
  130.        : "cc")
  131. #define PERFORM_ADC_CIO(d, co, r1, r2, ci) \
  132.   asm ("subcc %4,1,%%g0        ! cy = (CI == 0)
  133.     subxcc %2,%3,%0        ! subtract R2 from R1
  134.     subx %%g0,-1,%1        ! set CO to !cy"            \
  135.        : "=&r" (d), "=r" (co)                        \
  136.        : "r" (r1), "rI" (r2), "rI" (ci)                    \
  137.        : "cc")
  138. #define PERFORM_ADC_CO(d, co, r1, r2, ci) \
  139.   asm ("subcc %2,%3,%0        ! subtract R2 from R1
  140.     subx %%g0,-1,%1        ! set CO to !cy"            \
  141.        : "=&r" (d), "=r" (co)                        \
  142.        : "r" (r1), "rI" (r2)                        \
  143.        : "cc")
  144. #endif /* sparc */
  145.  
  146. #if m88k
  147. #define PERFORM_ADD_CIO(d, co, r1, r2, ci) \
  148.   asm ("or %0,r0,1
  149.     subu.co r0,%4,%0    ; set cy if CI != 0
  150.     addu.cio %0,%2,%r3    ; add R1 and R2
  151.     addu.ci %1,r0,r0    ; set CO to cy"                \
  152.        : "=&r" (d), "=r" (co)                        \
  153.        : "%r" (r1), "Or" (r2), "r" (ci))
  154. #define PERFORM_ADD_CO(d, co, r1, r2, ci) \
  155.   asm ("addu.co %0,%2,%r3    ; add R1 and R2
  156.     addu.ci %1,r0,r0    ; set CO to cy"                \
  157.        : "=r" (d), "=r" (co)                        \
  158.        : "%r" (r1), "Or" (r2))
  159. #define PERFORM_SUB_CIO(d, co, r1, r2, ci) \
  160.   asm ("subu.co r0,r0,%r4    ; reset cy if CI != 0
  161.     subu.cio %0,%2,%r3    ; subtract R2 from R1
  162.     subu.ci %1,r0,r0    ; set CO to -1+cy
  163.     subu %1,r0,%1        ; set CO to !cy"            \
  164.        : "=r" (d), "=r" (co)                        \
  165.        : "r" (r1), "Or" (r2), "Or" (ci))
  166. #define PERFORM_SUB_CO(d, co, r1, r2, ci) \
  167.   asm ("subu.co %0,%2,%r3    ; subtract R2 from R1
  168.     subu.ci %1,r0,r0    ; set CO to -1+cy
  169.     subu %1,r0,%1        ; set CO to !cy"            \
  170.        : "=r" (d), "=r" (co)                        \
  171.        : "r" (r1), "Or" (r2))
  172. #define PERFORM_ADC_CIO(d, co, r1, r2, ci) \
  173.   asm ("or %0,r0,1
  174.     subu.co r0,%r4,%0    ; set cy if CI != 0
  175.     subu.cio %0,%2,%r3    ; subtract R2 from R1
  176.     addu.ci %1,r0,r0    ; set CO to cy"                \
  177.        : "=&r" (d), "=r" (co)                        \
  178.        : "r" (r1), "Or" (r2), "Or" (ci))
  179. #define PERFORM_ADC_CO(d, co, r1, r2, ci) \
  180.   asm ("subu.co %0,%2,%r3    ; subtract R2 from R1
  181.     addu.ci %1,r0,r0    ; set CO to cy"                \
  182.        : "=r" (d), "=r" (co)                        \
  183.        : "r" (r1), "Or" (r2))
  184. #endif /* m88k */
  185.  
  186. #endif /* __GNUC__ && USE_ASM*/
  187.  
  188. /************************* Default PERFORM_* in C *************************/
  189.  
  190. #define PERFORM_COPY(d, co, r1, ci) \
  191.   ((d) = (r1), (co) = (ci))
  192. #define PERFORM_EXCHANGE(co, r1, r2, ci) \
  193.   do {word __temp = (r1), (r1) = (r2), (r2) = __temp, (co) = (ci);} while (0)
  194.  
  195. #define PERFORM_ADD(d, co, r1, r2, ci) \
  196.   ((d) = (r1) + (r2), (co) = (ci))
  197. #ifndef PERFORM_ADD_CIO
  198. #define PERFORM_ADD_CIO(d, co, r1, r2, ci) \
  199.   do { word __d = (r1) + (ci);                        \
  200.        word __cy = __d < (ci);                        \
  201.        (d) = __d + (r2);                        \
  202.        (co) = ((d) < __d) + __cy; } while (0)
  203. #endif
  204. #ifndef PERFORM_ADD_CI
  205. #define PERFORM_ADD_CI(d, co, r1, r2, ci) \
  206.   do { word __d = (r1) + (r2) + (ci);                    \
  207.        (co) = (ci);                            \
  208.        (d) = __d; } while (0)
  209. #endif
  210. #ifndef PERFORM_ADD_CO
  211. #define PERFORM_ADD_CO(d, co, r1, r2, ci) \
  212.   do { word __d = (r1) + (r2);                        \
  213.        (co) = __d < (r1);                        \
  214.        (d) = __d; } while (0)
  215. #endif
  216.  
  217. #define PERFORM_SUB(d, co, r1, r2, ci) \
  218.   ((d) = (r1) - (r2), (co) = (ci))
  219. #ifndef PERFORM_SUB_CIO
  220. #define PERFORM_SUB_CIO(d, co, r1, r2, ci) \
  221.   do { word __d = (r1) - (r2) - (ci);                    \
  222.        (co) = (ci) ? __d >= (r1) : __d > (r1);                \
  223.        (d) = __d; } while (0)
  224. #endif
  225. #ifndef PERFORM_SUB_CI
  226. #define PERFORM_SUB_CI(d, co, r1, r2, ci) \
  227.   do { word __d = (r1) - (r2) - (ci);                    \
  228.        (co) = (ci);                            \
  229.        (d) = __d; } while (0)
  230. #endif
  231. #ifndef PERFORM_SUB_CO
  232. #define PERFORM_SUB_CO(d, co, r1, r2, ci) \
  233.   do { word __d = (r1) - (r2);                        \
  234.        (co) = __d > (r1);                        \
  235.        (d) = __d; } while (0)
  236. #endif
  237.  
  238. #ifndef PERFORM_ADC_CIO
  239. #define PERFORM_ADC_CIO(d, co, r1, r2, ci) \
  240.   do { word __d = (r1) + ~(r2) + (ci);                    \
  241.        (co) = (ci) ? __d <= (r1) : __d < (r1);                \
  242.        (d) = __d; } while (0)
  243. #endif
  244. #ifndef PERFORM_ADC_CI
  245. #define PERFORM_ADC_CI(d, co, r1, r2, ci) \
  246.   do { word __d = (r1) + ~(r2) + (ci);                    \
  247.        (co) = (ci);                            \
  248.        (d) = __d; } while (0)
  249. #endif
  250. #ifndef PERFORM_ADC_CO
  251. #define PERFORM_ADC_CO(d, co, r1, r2, ci) \
  252.   do { word __d = (r1) - (r2);                        \
  253.        (co) = __d <= (r1);                        \
  254.        (d) = __d; } while (0)
  255. #endif
  256.  
  257. #ifndef PERFORM_CMP
  258. #define PERFORM_CMP(d, co, r1, r2, ci) \
  259.   ((co) = (r1) < (r2))
  260. #endif
  261. #ifndef PERFORM_CMPPAR
  262. #define PERFORM_CMPPAR(d, co, r1, r2, ci) \
  263.   do {                                    \
  264.     word __x;                                \
  265.     union { long w; short h[2]; char b[4]; } __r1, __r2;        \
  266.     __r1.w = (r1); __r2.w = (r2);                    \
  267.     __x = ((__r1.h[0] != __r2.h[0]) && (__r1.h[1] != __r2.h[1])) << 14;    \
  268.     __x |= ((__r1.b[0] != __r2.b[0]) && (__r1.b[1] != __r2.b[1])    \
  269.        && (__r1.b[2] != __r2.b[2]) && (__r1.b[3] != __r2.b[3])) << 12; \
  270.     __x |= ((unsigned_word) (r1) >= (unsigned_word) (r2)) << 10;    \
  271.     __x |= ((unsigned_word) (r1) <= (unsigned_word) (r2)) << 8;        \
  272.     __x |= ((signed_word) (r1) >= (signed_word) (r2)) << 6;        \
  273.     __x |= ((signed_word) (r1) <= (signed_word) (r2)) << 4;        \
  274.     __x |= ((r1) != (r2)) << 2;                        \
  275.     (d) = __x + 0x5554;        /* binary 0101010101010100 */        \
  276.     (co) = (ci);                            \
  277.   } while (0)
  278. #endif
  279.  
  280. /* Logic operations that don't affect carry.  */
  281. #ifndef PERFORM_AND
  282. #define PERFORM_AND(d, co, r1, r2, ci) \
  283.   ((d) = (r1) & (r2), (co) = (ci))
  284. #endif
  285. #ifndef PERFORM_IOR
  286. #define PERFORM_IOR(d, co, r1, r2, ci) \
  287.   ((d) = (r1) | (r2), (co) = (ci))
  288. #endif
  289. #ifndef PERFORM_XOR
  290. #define PERFORM_XOR(d, co, r1, r2, ci) \
  291.   ((d) = (r1) ^ (r2), (co) = (ci))
  292. #endif
  293. #ifndef PERFORM_ANDC
  294. #define PERFORM_ANDC(d, co, r1, r2, ci) \
  295.   ((d) = (r1) & ~(r2), (co) = (ci))
  296. #endif
  297. #ifndef PERFORM_IORC
  298. #define PERFORM_IORC(d, co, r1, r2, ci) \
  299.   ((d) = (r1) | ~(r2), (co) = (ci))
  300. #endif
  301. #ifndef PERFORM_EQV
  302. #define PERFORM_EQV(d, co, r1, r2, ci) \
  303.   ((d) = (r1) ^ ~(r2), (co) = (ci))
  304. #endif
  305. #ifndef PERFORM_NAND
  306. #define PERFORM_NAND(d, co, r1, r2, ci) \
  307.   ((d) = ~((r1) & (r2)), (co) = (ci))
  308. #endif
  309. #ifndef PERFORM_NOR
  310. #define PERFORM_NOR(d, co, r1, r2, ci) \
  311.   ((d) = ~((r1) | (r2)), (co) = (ci))
  312. #endif
  313.  
  314. /* Logic operations that reset carry.  */
  315. #ifndef PERFORM_AND_RC
  316. #define PERFORM_AND_RC(d, co, r1, r2, ci) \
  317.   ((d) = (r1) & (r2), (co) = 0)
  318. #endif
  319. #ifndef PERFORM_IOR_RC
  320. #define PERFORM_IOR_RC(d, co, r1, r2, ci) \
  321.   ((d) = (r1) | (r2), (co) = 0)
  322. #endif
  323. #ifndef PERFORM_XOR_RC
  324. #define PERFORM_XOR_RC(d, co, r1, r2, ci) \
  325.   ((d) = (r1) ^ (r2), (co) = 0)
  326. #endif
  327. #ifndef PERFORM_ANDC_RC
  328. #define PERFORM_ANDC_RC(d, co, r1, r2, ci) \
  329.   ((d) = (r1) & ~(r2), (co) = 0)
  330. #endif
  331. #ifndef PERFORM_IORC_RC
  332. #define PERFORM_IORC_RC(d, co, r1, r2, ci) \
  333.   ((d) = (r1) | ~(r2), (co) = 0)
  334. #endif
  335. #ifndef PERFORM_EQV_RC
  336. #define PERFORM_EQV_RC(d, co, r1, r2, ci) \
  337.   ((d) = (r1) ^ ~(r2), (co) = 0)
  338. #endif
  339. #ifndef PERFORM_NAND_RC
  340. #define PERFORM_NAND_RC(d, co, r1, r2, ci) \
  341.   ((d) = ~((r1) & (r2)), (co) = 0)
  342. #endif
  343. #ifndef PERFORM_NOR_RC
  344. #define PERFORM_NOR_RC(d, co, r1, r2, ci) \
  345.   ((d) = ~((r1) | (r2)), (co) = 0)
  346. #endif
  347.  
  348. /* Logic operations that clobber carry.  */
  349. #ifndef PERFORM_AND_CC
  350. #define PERFORM_AND_CC(d, co, r1, r2, ci) \
  351.   ((d) = (r1) & (r2), (co) = -1)
  352. #endif
  353. #ifndef PERFORM_IOR_CC
  354. #define PERFORM_IOR_CC(d, co, r1, r2, ci) \
  355.   ((d) = (r1) | (r2), (co) = -1)
  356. #endif
  357. #ifndef PERFORM_XOR_CC
  358. #define PERFORM_XOR_CC(d, co, r1, r2, ci) \
  359.   ((d) = (r1) ^ (r2), (co) = -1)
  360. #endif
  361. #ifndef PERFORM_ANDC_CC
  362. #define PERFORM_ANDC_CC(d, co, r1, r2, ci) \
  363.   ((d) = (r1) & ~(r2), (co) = -1)
  364. #endif
  365. #ifndef PERFORM_IORC_CC
  366. #define PERFORM_IORC_CC(d, co, r1, r2, ci) \
  367.   ((d) = (r1) | ~(r2), (co) = -1)
  368. #endif
  369. #ifndef PERFORM_EQV_CC
  370. #define PERFORM_EQV_CC(d, co, r1, r2, ci) \
  371.   ((d) = (r1) ^ ~(r2), (co) = -1)
  372. #endif
  373. #ifndef PERFORM_NAND_CC
  374. #define PERFORM_NAND_CC(d, co, r1, r2, ci) \
  375.   ((d) = ~((r1) & (r2)), (co) = -1)
  376. #endif
  377. #ifndef PERFORM_NOR_CC
  378. #define PERFORM_NOR_CC(d, co, r1, r2, ci) \
  379.   ((d) = ~((r1) | (r2)), (co) = -1)
  380. #endif
  381.  
  382. #ifndef PERFORM_LSHIFTR
  383. #define PERFORM_LSHIFTR(d, co, r1, r2, ci) \
  384.   ((d) = ((unsigned_word) (r1) >> TRUNC_CNT(r2)),            \
  385.    (co) = (ci))
  386. #endif
  387. #ifndef PERFORM_ASHIFTR
  388. #define PERFORM_ASHIFTR(d, co, r1, r2, ci) \
  389.   ((d) = ((signed_word) (r1) >> TRUNC_CNT(r2)),                \
  390.    (co) = (ci))
  391. #endif
  392. #ifndef PERFORM_SHIFTL
  393. #define PERFORM_SHIFTL(d, co, r1, r2, ci) \
  394.   ((d) = ((signed_word) (r1) << TRUNC_CNT(r2)), (co) = (ci))
  395. #endif
  396. #ifndef PERFORM_ROTATEL
  397. #define PERFORM_ROTATEL(d, co, r1, r2, ci) \
  398.  ((d) = (r2) == 0 ? (r1)                        \
  399.   : ((r1) << TRUNC_CNT(r2)) | ((r1) >> TRUNC_CNT(BITS_PER_WORD - (r2))),\
  400.   (co) = (ci))
  401. #endif
  402. #ifndef PERFORM_LSHIFTR_CO
  403. #define PERFORM_LSHIFTR_CO(d, co, r1, r2, ci) \
  404.   do { word __d = ((unsigned_word) (r1) >> TRUNC_CNT(r2));        \
  405.        (co) = ((unsigned_word) (r1) >> (TRUNC_CNT(r2) - 1)) & 1;    \
  406.        (d) = __d; } while (0)
  407. #endif
  408. #ifndef PERFORM_ASHIFTR_CO
  409. #define PERFORM_ASHIFTR_CO(d, co, r1, r2, ci) \
  410.   do { word __d = ((signed_word) (r1) >> TRUNC_CNT(r2));        \
  411.        (co) = ((signed_word) (r1) >> (TRUNC_CNT(r2) - 1)) & 1;        \
  412.        (d) = __d; } while (0)
  413. #endif
  414. #ifndef PERFORM_ASHIFTR_CON
  415. #define PERFORM_ASHIFTR_CON(d, co, r1, r2, ci) \
  416.   do { word __d = ((signed_word) (r1) >> TRUNC_CNT(r2));        \
  417.      (co) = (signed_word) (r1) < 0                    \
  418.        && ((r1) << TRUNC_CNT(BITS_PER_WORD - (r2))) != 0;        \
  419.        (d) = __d; } while (0)
  420. #endif
  421. #ifndef PERFORM_SHIFTL_CO
  422. #define PERFORM_SHIFTL_CO(d, co, r1, r2, ci) \
  423.   do { word __d = ((signed_word) (r1) << TRUNC_CNT(r2));        \
  424.        (co) = ((r1) >> TRUNC_CNT(BITS_PER_WORD - (r2))) & 1;        \
  425.        (d) = __d; } while (0)
  426. #endif
  427. #ifndef PERFORM_ROTATEL_CO
  428. #define PERFORM_ROTATEL_CO(d, co, r1, r2, ci) \
  429.   ((d) = ((r1) << TRUNC_CNT(r2)) | ((r1) >> TRUNC_CNT(BITS_PER_WORD - (r2))),\
  430.    (co) = (d) & 1)
  431. #endif
  432. #ifndef PERFORM_ROTATEXL_CIO
  433. #define PERFORM_ROTATEXL_CIO(d, co, r1, r2, ci) \
  434.   do { word __d;  unsigned cnt = TRUNC_CNT(r2);                \
  435.        if (cnt == 1)                            \
  436.      {                                \
  437.        __d = ((r1) << 1) | (ci);                    \
  438.        (co) = (r1) >> (BITS_PER_WORD - 1);                \
  439.      }                                \
  440.        else                                \
  441.      {                                \
  442.        __d = ((r1) << cnt)                        \
  443.          | (ci) << (cnt - 1)                    \
  444.          | ((r1) >> (BITS_PER_WORD + 1 - cnt));            \
  445.        (co) = ((r1) >> (BITS_PER_WORD - cnt)) & 1;            \
  446.      }                                \
  447.        (d) = __d;                            \
  448.      } while (0)
  449. #endif
  450. #ifndef PERFORM_EXTS1
  451. #define PERFORM_EXTS1(d, co, r1, r2, ci) \
  452.   ((d) = ((signed_word) (r1) >> TRUNC_CNT(r2)) << 31 >> 31, (co) = (ci))
  453. #endif
  454. #ifndef PERFORM_EXTS2
  455. #define PERFORM_EXTS2(d, co, r1, r2, ci) \
  456.   ((d) = ((signed_word) (r1) >> TRUNC_CNT(r2)) << 30 >> 30, (co) = (ci))
  457. #endif
  458. #ifndef PERFORM_EXTU1
  459. #define PERFORM_EXTU1(d, co, r1, r2, ci) \
  460.   ((d) = ((unsigned_word) (r1) >> TRUNC_CNT(r2)) & 1, (co) = (ci))
  461. #endif
  462. #ifndef PERFORM_EXTU2
  463. #define PERFORM_EXTU2(d, co, r1, r2, ci) \
  464.   ((d) = ((unsigned_word) (r1) >> TRUNC_CNT(r2)) & 3, (co) = (ci))
  465. #endif
  466.  
  467. #ifndef PERFORM_DOZ
  468. #define PERFORM_DOZ(d, co, r1, r2, ci) \
  469.   (((d) = (signed_word) (r1) > (signed_word) (r2) ? (r1) - (r2) : 0),    \
  470.    (co) = (ci))
  471. #endif
  472.  
  473. #ifndef PERFORM_CPEQ
  474. #define PERFORM_CPEQ(d, co, r1, r2, ci) \
  475.   ((d) = ((r1) == (r2)) << 31, (co) = (ci))
  476. #endif
  477. #ifndef PERFORM_CPGE
  478. #define PERFORM_CPGE(d, co, r1, r2, ci) \
  479.   ((d) = ((signed_word) (r1) >= (signed_word) (r2)) << 31, (co) = (ci))
  480. #endif
  481. #ifndef PERFORM_CPGEU
  482. #define PERFORM_CPGEU(d, co, r1, r2, ci) \
  483.   ((d) = ((unsigned_word) (r1) >= (unsigned_word) (r2)) << 31, (co) = (ci))
  484. #endif
  485. #ifndef PERFORM_CPGT
  486. #define PERFORM_CPGT(d, co, r1, r2, ci) \
  487.   ((d) = ((signed_word) (r1) > (signed_word) (r2)) << 31, (co) = (ci))
  488. #endif
  489. #ifndef PERFORM_CPGTU
  490. #define PERFORM_CPGTU(d, co, r1, r2, ci) \
  491.   ((d) = ((unsigned_word) (r1) > (unsigned_word) (r2)) << 31, (co) = (ci))
  492. #endif
  493. #ifndef PERFORM_CPLE
  494. #define PERFORM_CPLE(d, co, r1, r2, ci) \
  495.   ((d) = ((signed_word) (r1) <= (signed_word) (r2)) << 31, (co) = (ci))
  496. #endif
  497. #ifndef PERFORM_CPLEU
  498. #define PERFORM_CPLEU(d, co, r1, r2, ci) \
  499.   ((d) = ((unsigned_word) (r1) <= (unsigned_word) (r2)) << 31, (co) = (ci))
  500. #endif
  501. #ifndef PERFORM_CPLT
  502. #define PERFORM_CPLT(d, co, r1, r2, ci) \
  503.   ((d) = ((signed_word) (r1) < (signed_word) (r2)) << 31, (co) = (ci))
  504. #endif
  505. #ifndef PERFORM_CPLTU
  506. #define PERFORM_CPLTU(d, co, r1, r2, ci) \
  507.   ((d) = ((unsigned_word) (r1) < (unsigned_word) (r2)) << 31, (co) = (ci))
  508. #endif
  509. #ifndef PERFORM_CPNEQ
  510. #define PERFORM_CPNEQ(d, co, r1, r2, ci) \
  511.   ((d) = ((r1) != (r2)) << 31, (co) = (ci))
  512. #endif
  513.  
  514. /* Unary operations.  */
  515. #ifndef PERFORM_CLZ
  516. #define PERFORM_CLZ(d, co, r1, ci) \
  517.   do {                                    \
  518.     int __a;                                \
  519.     __a = (r1) <= 0xffff                        \
  520.       ? ((r1) <= 0xff ? 0 : 8)                        \
  521.       : ((r1) <= 0xffffff ?  16 : 24);                    \
  522.     (d) = clz_tab[(r1) >> __a] - __a;                    \
  523.     (co) = (ci);                            \
  524.   } while (0)
  525. #endif
  526. #ifndef PERFORM_CTZ
  527. /* This can be done faster using the (x & -x) trick.  */
  528. #define PERFORM_CTZ(d, co, r1, ci) \
  529.   do {                                    \
  530.     int __a;                                \
  531.     __a = ((r1) & 0xffff == 0)                        \
  532.       ? (((r1) & 0xff0000) == 0 ? 24 : 16)                \
  533.       : ((r1) & 0xff == 0) ? 8 : 0;                    \
  534.     (d) = ctz_tab[((r1) >> __a) & 0xff] + __a;                \
  535.     (co) = (ci);                            \
  536.   } while (0)
  537. #endif
  538. #ifndef PERFORM_FF1
  539. #define PERFORM_FF1(d, co, r1, ci) \
  540.   do {                                    \
  541.     int __a;                                \
  542.     __a = (r1) <= 0xffff                        \
  543.       ? ((r1) <= 0xff ? 0 : 8)                        \
  544.       : ((r1) <= 0xffffff ?  16 : 24);                    \
  545.     (d) = ff1_tab[(r1) >> __a] + __a;                    \
  546.     (co) = (ci);                            \
  547.     FF1_CHECK(d,r1)                            \
  548.   } while (0)
  549. #endif
  550. #if m88k
  551. #define FF1_CHECK(d,r1)                            \
  552.   { int t;                                \
  553.     asm ("ff1 %0,%1" : "=r" (t) : "r" (r1));                \
  554.     if (t != (d)) abort (); }
  555. #else
  556. #define FF1_CHECK(d,r1)
  557. #endif
  558. #ifndef PERFORM_FF0
  559. #define PERFORM_FF0(d, co, r1, ci) \
  560.   PERFORM_FF1(d, co, ~(r1), ci)
  561. #endif
  562. #ifndef PERFORM_ABSVAL
  563. #define PERFORM_ABSVAL(d, co, r1, ci) \
  564.   ((d) = (signed_word) (r1) < 0 ? -(r1) : (r1), (co) = (ci))
  565. #endif
  566. #ifndef PERFORM_NABSVAL
  567. #define PERFORM_NABSVAL(d, co, r1, ci) \
  568.   ((d) = (signed_word) (r1) > 0 ? -(r1) : (r1), (co) = (ci))
  569. #endif
  570.  
  571. #ifndef PERFORM_INVDIV
  572. #define PERFORM_INVDIV(v, co, r1, ci) \
  573.   do {                                    \
  574.     word __q, __r;                            \
  575.     udiv_qrnnd (__q, __r, -(r1), 0, (r1));                \
  576.     (v) = __q;                                \
  577.     (co) = (ci);                            \
  578.   } while (0)
  579. #endif
  580. #ifndef PERFORM_INVMOD
  581. #define PERFORM_INVMOD(v, co, r1, ci) \
  582.   do {                                    \
  583.     word __q, __r;                            \
  584.     udiv_qrnnd (__q, __r, -(r1), 0, (r1));                \
  585.     (v) = __r;                                \
  586.     (co) = (ci);                            \
  587.   } while (0)
  588. #endif
  589. #ifndef PERFORM_MUL
  590. #define PERFORM_MUL(v, co, r1, r2, ci) \
  591.   do {                                    \
  592.     (v) = (r1) * (r2);                            \
  593.     (co) = (ci);                            \
  594.   } while (0)
  595. #endif
  596. #ifndef PERFORM_UMULWIDEN_HI
  597. #define PERFORM_UMULWIDEN_HI(v, co, r1, r2, ci) \
  598.   do {                                    \
  599.     word __ph, __pl;                            \
  600.     umul_ppmm (__ph, __pl, (r1), (r2));                    \
  601.     (v) = __ph;                                \
  602.     (co) = (ci);                            \
  603.   } while (0)
  604. #endif
  605.  
  606. #ifdef UDIV_WITH_SDIV
  607. #define PERFORM_SDIV(v, co, r1, r2, ci) \
  608.   do {                                    \
  609.     if ((r2) != 0)                            \
  610.       (v) = (signed_word) (r1) / (signed_word) (r2);            \
  611.     else                                \
  612.       (v) = 0;                                \
  613.     (co) = (ci);                            \
  614.     } while (0)
  615. #endif /* UDIV_WITH_SDIV */
  616.  
  617. enum goal_func
  618. {
  619. #undef    DEF_GOAL
  620. #define DEF_GOAL(SYM,ARITY,NAME,CODE) SYM,
  621. #undef    DEF_SYNONYM
  622. #define DEF_SYNONYM(SYM,NAME)
  623. #include "goal.def"
  624.   LAST_AND_UNUSED_GOAL_CODE
  625. };
  626.  
  627. enum prune_flags
  628. {
  629.   NO_PRUNE = 0,
  630.   CY_0 = 1,
  631.   CY_1 = 2,
  632.   CY_JUST_SET = 4,
  633. };
  634.  
  635. void
  636. synth(insn_t *sequence,
  637.       int n_insns,
  638.       word *values,
  639.       int n_values,
  640.       word desired_value,
  641.       int allowed_cost,
  642.       int cy_in,
  643.       int flags);
  644. void
  645. test_sequence(insn_t *sequence, int n_insns);
  646. int
  647. run_program(insn_t *sequence, int n_insns, word *values);
  648.  
  649. extern const char clz_tab[];
  650. extern const char ctz_tab[];
  651. extern const char ff1_tab[];
  652.